from logging import getLogger
from datetime import datetime

from zope.interface import implements

from meercat.interfaces import IResource, IInstance, IMetadata, IPickleable



log = getLogger('meercat.base.instance')

class Instance(object):
    """ A basic implementation of the IInstance interface. Simply stores all
    information as attributes on the object """
    
    implements(IInstance, IPickleable)
    
    def __init__(self,
                 source=None,
                 identifier=None,
                 active=True,
                 metadata=[],
                 modified=None,
                 resource=None):
        self._source = source
        self._identifier = identifier
        self._active = active
        log.debug('%s making sure that metadata is pickleable' % (str(self),))
        self._metadata = set(map(lambda m: IPickleable(IMetadata(m)), metadata))
        
        if resource is not None:
            self._resource = IPickleable(IResource(resource))
        else:
            self._resource = None
        
        if modified is None:
            self._modified = datetime.now()
        else:
            assert isinstance(modified, datetime)
            self._modified = modified
        
        log.debug('%s setting instance on metadata' % (str(self),))
        for m in self._metadata:
            if m.getInstance() != self:
                m._instance = self
    
    def __len__(self):
        return len(self._metadata)
    
    def __iter__(self):
        return self._metadata.__iter__()
    
    def __hash__(self):
        return hash((self.getSource(),self.getIdentifier(),))
    
    def __eq__(self, other):
        if not IInstance.providedBy(other):
            return False
        
        return (other.getIdentifier() == self.getIdentifier() and
                other.getSource() == self.getSource())
    
    def __unicode__(self):
        return u'Instance(source=%s,identifier=%s,active=%s)' % (unicode(self._source),
                                                                 unicode(self._identifier),
                                                                 unicode(self._active))
    
    def isActive(self):
        return self._active
      
    def getSource(self):
        return self._source
    
    def getIdentifier(self):
        return self._identifier
    
    def getMetadata(self):
        return self._metadata
    
    def getLastModified(self):
        return self._modified
    
    def getResource(self):
        return self._resource